/**
 * 天干地支关系工具类
 * 
 * 提供天干地支之间各种关系的检测和计算功能，包括：
 * - 天干关系：相冲、相克、五合
 * - 地支关系：六合、三合、三会、半合、暗合、相刑、相冲、相破、相害、暗合局、拱合局、暗三会局、拱三会局、四合土局
 * - 流通关系：相生、相助
 * - 整柱关系：盖头、截脚
 * - 合化信息：各种合局的化气
 */

import { GANZHI_WUXING } from './wuxing'

// ==================== 天干关系映射表 ====================

/**
 * 天干相冲关系映射表
 * 相冲关系：甲_庚、乙_辛、丙_壬、丁_癸
 * 双向映射，如：甲冲庚，庚也冲甲
 */
const TIANGAN_CHONG: Record<string, string> = {
  '甲': '庚', '庚': '甲', '乙': '辛', '辛': '乙',
  '丙': '壬', '壬': '丙', '丁': '癸', '癸': '丁'
}

/**
 * 天干五合关系映射表
 * 五合关系：甲_己合化土、乙_庚合化金、丙_辛合化水、丁_壬合化木、戊_癸合化火
 * 双向映射，如：甲合己，己也合甲
 */
const TIANGAN_HE: Record<string, string> = {
  '甲': '己', '己': '甲', '乙': '庚', '庚': '乙',
  '丙': '辛', '辛': '丙', '丁': '壬', '壬': '丁',
  '戊': '癸', '癸': '戊'
}

// ==================== 地支关系映射表 ====================

/**
 * 地支六合关系映射表
 * 六合关系：子_丑合化土、寅_亥合化木、卯_戌合化火、辰_酉合化金、巳_申合化水、午_未合化火
 * 双向映射，如：子合丑，丑也合子
 */
const DIZHI_LIUHE: Record<string, string> = {
  '子': '丑', '丑': '子', '寅': '亥', '亥': '寅',
  '卯': '戌', '戌': '卯', '辰': '酉', '酉': '辰',
  '巳': '申', '申': '巳', '午': '未', '未': '午'
}

/**
 * 地支相冲关系映射表
 * 相冲关系：子_午、丑_未、寅_申、卯_酉、辰_戌、巳_亥
 * 双向映射，如：子冲午，午也冲子
 */
const DIZHI_CHONG: Record<string, string> = {
  '子': '午', '午': '子', '丑': '未', '未': '丑',
  '寅': '申', '申': '寅', '卯': '酉', '酉': '卯',
  '辰': '戌', '戌': '辰', '巳': '亥', '亥': '巳'
}

/**
 * 地支相破关系映射表
 * 相破关系：子_酉、午_卯、巳_申、辰_丑、寅_亥、戌_未
 * 双向映射，如：子破酉，酉也破子
 */
const DIZHI_PO: Record<string, string> = {
  '子': '酉', '酉': '子', '寅': '亥', '亥': '寅',
  '卯': '午', '午': '卯', '辰': '丑', '丑': '辰',
  '巳': '申', '申': '巳', '未': '戌', '戌': '未'
}

/**
 * 地支相害关系映射表
 * 相害关系：子_未、丑_午、寅_巳、卯_辰、申_亥、酉_戌
 * 双向映射，如：子害未，未也害子
 */
const DIZHI_HAI: Record<string, string> = {
  '子': '未', '未': '子', '丑': '午', '午': '丑',
  '寅': '巳', '巳': '寅', '卯': '辰', '辰': '卯',
  '申': '亥', '亥': '申', '酉': '戌', '戌': '酉'
}

/**
 * 地支三合局映射表
 * 三合局：申_子_辰三合水局、寅_午_戌三合火局、巳_酉_丑三合金局、亥_卯_未三合木局
 * 每个地支都映射到完整的三合局数组
 */
const DIZHI_SANHE: Record<string, string[]> = {
  '申': ['申', '子', '辰'], '子': ['申', '子', '辰'], '辰': ['申', '子', '辰'],
  '亥': ['亥', '卯', '未'], '卯': ['亥', '卯', '未'], '未': ['亥', '卯', '未'],
  '寅': ['寅', '午', '戌'], '午': ['寅', '午', '戌'], '戌': ['寅', '午', '戌'],
  '巳': ['巳', '酉', '丑'], '酉': ['巳', '酉', '丑'], '丑': ['巳', '酉', '丑']
}

/**
 * 地支三会局映射表
 * 三会局：寅_卯_辰三会木局、巳_午_未三会火局、申_酉_戌三会金局、亥_子_丑三会水局
 * 每个地支都映射到完整的三会局数组
 */
const DIZHI_SANHUI: Record<string, string[]> = {
  '寅': ['寅', '卯', '辰'], '卯': ['寅', '卯', '辰'], '辰': ['寅', '卯', '辰'],
  '巳': ['巳', '午', '未'], '午': ['巳', '午', '未'], '未': ['巳', '午', '未'],
  '申': ['申', '酉', '戌'], '酉': ['申', '酉', '戌'], '戌': ['申', '酉', '戌'],
  '亥': ['亥', '子', '丑'], '子': ['亥', '子', '丑'], '丑': ['亥', '子', '丑']
}

/**
 * 地支暗合关系映射表（严格按照数据中的9种组合）
 * 暗合关系：卯_申、午_亥、丑_寅、寅_未、子_戌、子_辰、巳_酉、寅_午、子_巳
 * 每个地支映射到可以与之暗合的地支数组
 */
const DIZHI_ANHE: Record<string, string[]> = {
  '子': ['巳', '辰', '戌'],  // 子_巳暗合、子_辰暗合、子_戌暗合
  '巳': ['子', '酉'],        // 子_巳暗合、巳_酉暗合
  '辰': ['子'],              // 子_辰暗合
  '酉': ['巳'],              // 巳_酉暗合
  '戌': ['子'],              // 子_戌暗合
  '寅': ['午', '未', '丑'],  // 寅_午暗合、寅_未暗合、丑_寅暗合
  '午': ['寅', '亥'],        // 寅_午暗合、午_亥暗合
  '未': ['寅'],              // 寅_未暗合
  '亥': ['午'],              // 午_亥暗合
  '卯': ['申'],              // 卯_申暗合
  '申': ['卯'],              // 卯_申暗合
  '丑': ['寅']               // 丑_寅暗合
}

/**
 * 地支相刑关系映射表
 * 相刑关系包括：
 * - 三刑：寅_巳_申三刑、丑_戌_未三刑
 * - 相刑：寅_巳、巳_申、申_寅、丑_戌、戌_未、未_丑、子_卯
 * - 自刑：辰_辰、午_午、酉_酉、亥_亥
 * 每个地支映射到可以与之相刑的地支数组
 */
const DIZHI_XING: Record<string, string[]> = {
  '子': ['卯'], '卯': ['子'], '寅': ['巳', '申'], '巳': ['申', '寅'],
  '申': ['寅', '巳'], '丑': ['戌', '未'], '戌': ['未', '丑'], '未': ['丑', '戌'],
  '辰': ['辰'], '午': ['午'], '酉': ['酉'], '亥': ['亥']
}

// ==================== 五行关系映射表 ====================

/**
 * 五行相生关系映射表
 * 相生关系：木生火、火生土、土生金、金生水、水生木
 * 单向映射，如：木生火，但火不生木
 */
const WUXING_SHENG: Record<string, string> = {
  '木': '火', '火': '土', '土': '金', '金': '水', '水': '木'
}

/**
 * 五行相克关系映射表
 * 相克关系：木克土、火克金、土克水、金克木、水克火
 * 每个五行映射到被其克制的五行数组
 */
const WUXING_KE: Record<string, string[]> = {
  '木': ['土'], '火': ['金'], '土': ['水'], '金': ['木'], '水': ['火']
}

// ==================== 天干相克关系映射表 ====================

/**
 * 天干相克关系映射表（严格按照数据中的10种组合）
 * 相克关系：甲_戊、乙_己、丙_庚、丁_辛、戊_壬、己_癸、庚_甲、辛_乙、壬_丙、癸_丁
 * 每个天干映射到被其克制的天干数组
 * 注意：相克是单向的，如甲克戊，但戊不克甲
 */
const TIANGAN_KE: Record<string, string[]> = {
  '甲': ['戊'],      // 甲_戊相克
  '乙': ['己'],      // 乙_己相克
  '丙': ['庚'],      // 丙_庚相克
  '丁': ['辛'],      // 丁_辛相克
  '戊': ['壬'],      // 戊_壬相克
  '己': ['癸'],      // 己_癸相克
  '庚': ['甲'],      // 庚_甲相克
  '辛': ['乙'],      // 辛_乙相克
  '壬': ['丙'],      // 壬_丙相克
  '癸': ['丁']       // 癸_丁相克
}

// ==================== 天干关系检测函数 ====================

/**
 * 判断两个天干是否相冲
 * @param gan1 第一个天干
 * @param gan2 第二个天干
 * @returns 如果相冲返回 true，否则返回 false
 */
export function isTianganChong(gan1: string, gan2: string): boolean {
  return TIANGAN_CHONG[gan1] === gan2
}

/**
 * 判断两个天干是否相克（gan1克gan2）
 * @param gan1 第一个天干
 * @param gan2 第二个天干
 * @returns 如果 gan1 克 gan2 返回 true，否则返回 false
 * @note 相克是单向的，需要检查两个方向：isTianganKe(gan1, gan2) 或 isTianganKe(gan2, gan1)
 */
export function isTianganKe(gan1: string, gan2: string): boolean {
  return TIANGAN_KE[gan1]?.includes(gan2) ?? false
}

/**
 * 判断两个天干是否五合
 * @param gan1 第一个天干
 * @param gan2 第二个天干
 * @returns 如果五合返回 true，否则返回 false
 */
export function isTianganHe(gan1: string, gan2: string): boolean {
  return TIANGAN_HE[gan1] === gan2
}

// ==================== 地支关系检测函数 ====================

/**
 * 判断两个地支是否六合
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果六合返回 true，否则返回 false
 */
export function isDizhiLiuhe(zhi1: string, zhi2: string): boolean {
  return DIZHI_LIUHE[zhi1] === zhi2
}

/**
 * 判断三个地支是否三合
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param zhi3 第三个地支
 * @returns 如果三合返回 true，否则返回 false
 */
export function isDizhiSanhe(zhi1: string, zhi2: string, zhi3: string): boolean {
  const set = DIZHI_SANHE[zhi1]
  if (!set) return false
  // 检查三个地支是否都在同一个三合局中，且互不相同
  return set.includes(zhi2) && set.includes(zhi3) && new Set([zhi1, zhi2, zhi3]).size === 3
}

/**
 * 判断三个地支是否三会
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param zhi3 第三个地支
 * @returns 如果三会返回 true，否则返回 false
 */
export function isDizhiSanhui(zhi1: string, zhi2: string, zhi3: string): boolean {
  const set = DIZHI_SANHUI[zhi1]
  if (!set) return false
  // 检查三个地支是否都在同一个三会局中，且互不相同
  return set.includes(zhi2) && set.includes(zhi3) && new Set([zhi1, zhi2, zhi3]).size === 3
}

/**
 * 判断四个地支是否四合土局（丑_辰_未_戌合土局）
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param zhi3 第三个地支
 * @param zhi4 第四个地支
 * @returns 如果四合土局返回 true，否则返回 false
 */
export function isDizhiSiheTu(zhi1: string, zhi2: string, zhi3: string, zhi4: string): boolean {
  const siheTu = ['丑', '辰', '未', '戌']
  const zhilist = [zhi1, zhi2, zhi3, zhi4]
  // 检查是否包含所有四个地支，且互不相同
  return siheTu.every(zhi => zhilist.includes(zhi)) && new Set(zhilist).size === 4
}

/**
 * 判断两个地支是否暗合
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果暗合返回 true，否则返回 false
 */
export function isDizhiAnhe(zhi1: string, zhi2: string): boolean {
  return DIZHI_ANHE[zhi1]?.includes(zhi2) ?? false
}

/**
 * 判断两个地支是否相刑
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果相刑返回 true，否则返回 false
 * @note 包括三刑、相刑和自刑
 */
export function isDizhiXing(zhi1: string, zhi2: string): boolean {
  return DIZHI_XING[zhi1]?.includes(zhi2) ?? false
}

/**
 * 判断两个地支是否相冲
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果相冲返回 true，否则返回 false
 */
export function isDizhiChong(zhi1: string, zhi2: string): boolean {
  return DIZHI_CHONG[zhi1] === zhi2
}

/**
 * 判断两个地支是否相破
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果相破返回 true，否则返回 false
 */
export function isDizhiPo(zhi1: string, zhi2: string): boolean {
  return DIZHI_PO[zhi1] === zhi2
}

/**
 * 判断两个地支是否相害
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果相害返回 true，否则返回 false
 */
export function isDizhiHai(zhi1: string, zhi2: string): boolean {
  return DIZHI_HAI[zhi1] === zhi2
}

// ==================== 流通关系检测函数（相生、相助） ====================

/**
 * 判断五行是否相生（wx1生wx2）
 * @param wx1 第一个五行
 * @param wx2 第二个五行
 * @returns 如果 wx1 生 wx2 返回 true，否则返回 false
 */
export function isWuxingSheng(wx1: string, wx2: string): boolean {
  return WUXING_SHENG[wx1] === wx2
}

/**
 * 判断五行是否相助（比肩劫财，即同五行）
 * @param wx1 第一个五行
 * @param wx2 第二个五行
 * @returns 如果五行相同返回 true，否则返回 false
 */
export function isWuxingZhu(wx1: string, wx2: string): boolean {
  return wx1 === wx2
}

/**
 * 判断天干是否相生（gan1生gan2）
 * @param gan1 第一个天干
 * @param gan2 第二个天干
 * @returns 如果 gan1 的五行生 gan2 的五行返回 true，否则返回 false
 */
export function isTianganSheng(gan1: string, gan2: string): boolean {
  const wx1 = GANZHI_WUXING[gan1]
  const wx2 = GANZHI_WUXING[gan2]
  return wx1 && wx2 ? isWuxingSheng(wx1, wx2) : false
}

/**
 * 判断天干是否相助（gan1助gan2，比肩劫财）
 * @param gan1 第一个天干
 * @param gan2 第二个天干
 * @returns 如果两个天干的五行相同返回 true，否则返回 false
 */
export function isTianganZhu(gan1: string, gan2: string): boolean {
  const wx1 = GANZHI_WUXING[gan1]
  const wx2 = GANZHI_WUXING[gan2]
  return wx1 && wx2 ? isWuxingZhu(wx1, wx2) : false
}

/**
 * 判断地支是否相生（zhi1生zhi2）
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果 zhi1 的五行生 zhi2 的五行返回 true，否则返回 false
 */
export function isDizhiSheng(zhi1: string, zhi2: string): boolean {
  const wx1 = GANZHI_WUXING[zhi1]
  const wx2 = GANZHI_WUXING[zhi2]
  return wx1 && wx2 ? isWuxingSheng(wx1, wx2) : false
}

/**
 * 判断地支是否相助（zhi1助zhi2，比肩劫财）
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 如果两个地支的五行相同返回 true，否则返回 false
 */
export function isDizhiZhu(zhi1: string, zhi2: string): boolean {
  const wx1 = GANZHI_WUXING[zhi1]
  const wx2 = GANZHI_WUXING[zhi2]
  return wx1 && wx2 ? isWuxingZhu(wx1, wx2) : false
}

/**
 * 判断同柱天干地支是否相生（gan生zhi或zhi生gan）
 * @param gan 天干
 * @param zhi 地支
 * @returns 如果天干生地支或地支生天干返回 true，否则返回 false
 */
export function isPillarSheng(gan: string, zhi: string): boolean {
  const ganWx = GANZHI_WUXING[gan]
  const zhiWx = GANZHI_WUXING[zhi]
  return ganWx && zhiWx ? (isWuxingSheng(ganWx, zhiWx) || isWuxingSheng(zhiWx, ganWx)) : false
}

/**
 * 判断同柱天干地支是否相助（比肩劫财）
 * @param gan 天干
 * @param zhi 地支
 * @returns 如果天干和地支的五行相同返回 true，否则返回 false
 */
export function isPillarZhu(gan: string, zhi: string): boolean {
  const ganWx = GANZHI_WUXING[gan]
  const zhiWx = GANZHI_WUXING[zhi]
  return ganWx && zhiWx ? isWuxingZhu(ganWx, zhiWx) : false
}

// ==================== 整柱关系检测函数 ====================

/**
 * 判断五行是否相克（wx1克wx2）
 * @param wx1 第一个五行
 * @param wx2 第二个五行
 * @returns 如果 wx1 克 wx2 返回 true，否则返回 false
 */
function isWuxingKe(wx1: string, wx2: string): boolean {
  return WUXING_KE[wx1]?.includes(wx2) ?? false
}

/**
 * 判断同柱天干地支是否盖头（天干克地支）
 * @param gan 天干
 * @param zhi 地支
 * @returns 如果天干克地支返回 true，否则返回 false
 */
export function isGaitou(gan: string, zhi: string): boolean {
  const ganWx = GANZHI_WUXING[gan]
  const zhiWx = GANZHI_WUXING[zhi]
  return ganWx && zhiWx ? isWuxingKe(ganWx, zhiWx) : false
}

/**
 * 判断同柱天干地支是否截脚（地支克天干）
 * @param gan 天干
 * @param zhi 地支
 * @returns 如果地支克天干返回 true，否则返回 false
 */
export function isJiejiao(gan: string, zhi: string): boolean {
  const ganWx = GANZHI_WUXING[gan]
  const zhiWx = GANZHI_WUXING[zhi]
  return ganWx && zhiWx ? isWuxingKe(zhiWx, ganWx) : false
}

/**
 * 获取同柱天干地支的所有关系
 * @param gan 天干
 * @param zhi 地支
 * @returns 关系数组，可能包含：'盖头'、'截脚'
 */
export function getPillarRelation(gan: string, zhi: string): string[] {
  const relations: string[] = []
  if (isGaitou(gan, zhi)) relations.push('盖头')
  if (isJiejiao(gan, zhi)) relations.push('截脚')
  return relations
}

// ==================== 合化信息映射表 ====================

/**
 * 天干五合化气映射表
 * 五合化气：甲_己合化土、乙_庚合化金、丙_辛合化水、丁_壬合化木、戊_癸合化火
 * 每个天干映射到其合化后的五行
 */
export const TIANGAN_HEHUA: Record<string, string> = {
  '甲': '土', '己': '土', '乙': '金', '庚': '金',
  '丙': '水', '辛': '水', '丁': '木', '壬': '木',
  '戊': '火', '癸': '火'
}

/**
 * 地支六合化气映射表
 * 六合化气：子_丑合化土、寅_亥合化木、卯_戌合化火、辰_酉合化金、巳_申合化水、午_未合化火
 * 每个地支映射到其合化后的五行
 */
export const DIZHI_LIUHE_HUAHUA: Record<string, string> = {
  '子': '土', '丑': '土', '寅': '木', '亥': '木',
  '卯': '火', '戌': '火', '辰': '金', '酉': '金',
  '巳': '水', '申': '水', '午': '火', '未': '火'
}

/**
 * 地支三合化气映射表
 * 三合化气：申_子_辰三合水局、寅_午_戌三合火局、巳_酉_丑三合金局、亥_卯_未三合木局
 * 每个地支映射到其所在三合局的化气
 */
export const DIZHI_SANHE_HUAHUA: Record<string, string> = {
  '申': '水', '子': '水', '辰': '水',
  '寅': '火', '午': '火', '戌': '火',
  '巳': '金', '酉': '金', '丑': '金',
  '亥': '木', '卯': '木', '未': '木'
}

/**
 * 地支三会化气映射表
 * 三会化气：寅_卯_辰三会木局、巳_午_未三会火局、申_酉_戌三会金局、亥_子_丑三会水局
 * 每个地支映射到其所在三会局的化气
 */
export const DIZHI_SANHUI_HUAHUA: Record<string, string> = {
  '寅': '木', '卯': '木', '辰': '木',
  '巳': '火', '午': '火', '未': '火',
  '申': '金', '酉': '金', '戌': '金',
  '亥': '水', '子': '水', '丑': '水'
}

// ==================== 合化信息获取函数 ====================

/**
 * 获取天干五合的化气
 * @param gan1 第一个天干
 * @param gan2 第二个天干
 * @returns 合化后的五行，如果不满足五合条件返回 null
 */
export function getTianganHehua(gan1: string, gan2: string): string | null {
  if (!isTianganHe(gan1, gan2)) return null
  return TIANGAN_HEHUA[gan1] || null
}

/**
 * 获取地支六合的化气
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 合化后的五行，如果不满足六合条件返回 null
 */
export function getDizhiLiuheHuahua(zhi1: string, zhi2: string): string | null {
  if (!isDizhiLiuhe(zhi1, zhi2)) return null
  return DIZHI_LIUHE_HUAHUA[zhi1] || null
}

/**
 * 获取地支三合的化气
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param zhi3 第三个地支
 * @returns 合化后的五行，如果不满足三合条件返回 null
 * @note 任意一个地支都能确定化气，因为同一三合局的所有地支化气相同
 */
export function getDizhiSanheHuahua(zhi1: string, zhi2: string, zhi3: string): string | null {
  if (!isDizhiSanhe(zhi1, zhi2, zhi3)) return null
  // 任意一个地支都能确定化气
  return DIZHI_SANHE_HUAHUA[zhi1] || DIZHI_SANHE_HUAHUA[zhi2] || DIZHI_SANHE_HUAHUA[zhi3] || null
}

/**
 * 获取地支三会的化气
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param zhi3 第三个地支
 * @returns 合化后的五行，如果不满足三会条件返回 null
 * @note 任意一个地支都能确定化气，因为同一三会局的所有地支化气相同
 */
export function getDizhiSanhuiHuahua(zhi1: string, zhi2: string, zhi3: string): string | null {
  if (!isDizhiSanhui(zhi1, zhi2, zhi3)) return null
  // 任意一个地支都能确定化气
  return DIZHI_SANHUI_HUAHUA[zhi1] || DIZHI_SANHUI_HUAHUA[zhi2] || DIZHI_SANHUI_HUAHUA[zhi3] || null
}

/**
 * 判断是否是半合（三合局缺少中间地支）
 * 半合是指三合局中相邻的两个地支（缺少中间地支）
 * - 申子辰：申子（半合）、子辰（半合）
 * - 亥卯未：亥卯（半合）、卯未（半合）
 * - 寅午戌：寅午（半合）、午戌（半合）
 * - 巳酉丑：巳酉（半合）、酉丑（半合）
 * 
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 返回对象，包含 isBanhe（是否半合）和 huahua（化气）
 */
export function isDizhiBanhe(zhi1: string, zhi2: string): { isBanhe: boolean; huahua: string | null } {
  // 检查是否属于三合局的两个地支
  for (const [key, set] of Object.entries(DIZHI_SANHE)) {
    if (set.includes(zhi1) && set.includes(zhi2) && zhi1 !== zhi2) {
      // 获取两个地支在三合局中的位置
      const idx1 = set.indexOf(zhi1)
      const idx2 = set.indexOf(zhi2)
      
      // 如果两个地支的位置相差1（相邻），说明是半合（缺少中间地支）
      // 三合局的顺序：0-1-2，相邻的是 0-1 或 1-2
      const diff = Math.abs(idx1 - idx2)
      if (diff === 1) {
        // 相邻的两个地支，是半合
        return { isBanhe: true, huahua: DIZHI_SANHE_HUAHUA[key] || null }
      }
    }
  }
  return { isBanhe: false, huahua: null }
}

/**
 * 判断是否是拱三会（三会局缺少中间地支）
 * 拱三会：寅辰拱会卯、巳未拱会午、申戌拱会酉、亥丑拱会子
 * 
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 返回对象，包含 isGongSanhui（是否拱三会）、huahua（化气）和 middleZhi（中间地支）
 */
export function isDizhiGongSanhui(zhi1: string, zhi2: string): { isGongSanhui: boolean; huahua: string | null; middleZhi: string | null } {
  // 拱三会的组合
  const gongSanhuiPairs: Record<string, { middle: string; huahua: string }> = {
    '寅辰': { middle: '卯', huahua: '木' },
    '辰寅': { middle: '卯', huahua: '木' },
    '巳未': { middle: '午', huahua: '火' },
    '未巳': { middle: '午', huahua: '火' },
    '申戌': { middle: '酉', huahua: '金' },
    '戌申': { middle: '酉', huahua: '金' },
    '亥丑': { middle: '子', huahua: '水' },
    '丑亥': { middle: '子', huahua: '水' }
  }
  
  const key = `${zhi1}${zhi2}`
  const pair = gongSanhuiPairs[key]
  
  if (pair) {
    return { 
      isGongSanhui: true, 
      huahua: pair.huahua,
      middleZhi: pair.middle
    }
  }
  
  return { isGongSanhui: false, huahua: null, middleZhi: null }
}

/**
 * 判断是否是暗合局（暗三合）- 需要两个地支配合天干
 * 暗合局：
 * - 地支见申_辰，天干见癸
 * - 地支见亥_未，天干见乙
 * - 地支见寅_戌，天干见丁
 * - 地支见巳_丑，天干见辛
 * 
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param gans 天干数组，用于检查是否包含所需的天干
 * @returns 返回对象，包含 isAnheJu（是否暗合局）和 huahua（化气）
 */
export function isDizhiAnheJu(
  zhi1: string, 
  zhi2: string, 
  gans: string[]
): { isAnheJu: boolean; huahua: string | null } {
  // 暗合局的组合（地支对 -> 需要的天干 -> 化气）
  const anheJuPairs: Record<string, { requiredGan: string; huahua: string }> = {
    '申辰': { requiredGan: '癸', huahua: '水' },
    '辰申': { requiredGan: '癸', huahua: '水' },
    '亥未': { requiredGan: '乙', huahua: '木' },
    '未亥': { requiredGan: '乙', huahua: '木' },
    '寅戌': { requiredGan: '丁', huahua: '火' },
    '戌寅': { requiredGan: '丁', huahua: '火' },
    '巳丑': { requiredGan: '辛', huahua: '金' },
    '丑巳': { requiredGan: '辛', huahua: '金' }
  }
  
  const key = `${zhi1}${zhi2}`
  const pair = anheJuPairs[key]
  
  if (pair && gans.includes(pair.requiredGan)) {
    return { 
      isAnheJu: true, 
      huahua: pair.huahua
    }
  }
  
  return { isAnheJu: false, huahua: null }
}

/**
 * 判断是否是拱合局（拱三合）- 需要两个地支
 * 拱合局：
 * - 申_辰拱合子
 * - 亥_未拱合卯
 * - 寅_戌拱合午
 * - 巳_丑拱合酉
 * 
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @returns 返回对象，包含 isGonghe（是否拱合局）、huahua（化气）和 middleZhi（中间地支）
 */
export function isDizhiGonghe(zhi1: string, zhi2: string): { isGonghe: boolean; huahua: string | null; middleZhi: string | null } {
  // 拱合局的组合
  const gonghePairs: Record<string, { middle: string; huahua: string }> = {
    '申辰': { middle: '子', huahua: '水' },
    '辰申': { middle: '子', huahua: '水' },
    '亥未': { middle: '卯', huahua: '木' },
    '未亥': { middle: '卯', huahua: '木' },
    '寅戌': { middle: '午', huahua: '火' },
    '戌寅': { middle: '午', huahua: '火' },
    '巳丑': { middle: '酉', huahua: '金' },
    '丑巳': { middle: '酉', huahua: '金' }
  }
  
  const key = `${zhi1}${zhi2}`
  const pair = gonghePairs[key]
  
  if (pair) {
    return { 
      isGonghe: true, 
      huahua: pair.huahua,
      middleZhi: pair.middle
    }
  }
  
  return { isGonghe: false, huahua: null, middleZhi: null }
}

/**
 * 判断是否是暗三会局 - 需要两个地支配合天干
 * 暗三会局：
 * - 地支见寅_辰，天干见乙
 * - 地支见巳_未，天干见丁
 * - 地支见申_戌，天干见辛
 * - 地支见亥_丑，天干见癸
 * 
 * @param zhi1 第一个地支
 * @param zhi2 第二个地支
 * @param gans 天干数组，用于检查是否包含所需的天干
 * @returns 返回对象，包含 isAnSanhui（是否暗三会局）、huahua（化气）和 middleZhi（中间地支）
 */
export function isDizhiAnSanhui(
  zhi1: string, 
  zhi2: string, 
  gans: string[]
): { isAnSanhui: boolean; huahua: string | null; middleZhi: string | null } {
  // 暗三会局的组合（地支对 -> 需要的天干 -> 中间地支和化气）
  const anSanhuiPairs: Record<string, { requiredGan: string; middle: string; huahua: string }> = {
    '寅辰': { requiredGan: '乙', middle: '卯', huahua: '木' },
    '辰寅': { requiredGan: '乙', middle: '卯', huahua: '木' },
    '巳未': { requiredGan: '丁', middle: '午', huahua: '火' },
    '未巳': { requiredGan: '丁', middle: '午', huahua: '火' },
    '申戌': { requiredGan: '辛', middle: '酉', huahua: '金' },
    '戌申': { requiredGan: '辛', middle: '酉', huahua: '金' },
    '亥丑': { requiredGan: '癸', middle: '子', huahua: '水' },
    '丑亥': { requiredGan: '癸', middle: '子', huahua: '水' }
  }
  
  const key = `${zhi1}${zhi2}`
  const pair = anSanhuiPairs[key]
  
  if (pair && gans.includes(pair.requiredGan)) {
    return { 
      isAnSanhui: true, 
      huahua: pair.huahua,
      middleZhi: pair.middle
    }
  }
  
  return { isAnSanhui: false, huahua: null, middleZhi: null }
}
